package streamforce.crypto.event;

import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import streamforce.crypto.KPAbe;

/**
 * Follow the schema in Esper's benchmark. 
 * <timestamp, stockName, price, volume> 
 */
public class StockEvent extends AbstractEvent implements Serializable{
	private final Log log = LogFactory.getLog(StockEvent.class);
	private Map<String, Ciphertext> price, volume;		
	
	public StockEvent(int ts, int hour, int sid){
		super(ts,hour,sid);
		this.price = new HashMap<String,Ciphertext>();
		this.volume = new HashMap<String,Ciphertext>();		
	}
	//encrypting the data
	//the windowSizes passed as an argument here is not necessary the same
	//global windowSizes. The owner can pass a subset of the latter. Only for 
	//Aggregate1 scheme that the global windowSize set is used
	public void initialization(KPAbe cryptoHandler, int timestamp,
			int stockId, int price, int volume, int[] windowSizes) {
		
		this.price = new HashMap<String,Ciphertext>();
		this.volume = new HashMap<String,Ciphertext>();
		
		long start = System.currentTimeMillis();
		
		String[] attributes = new String[3];
		attributes[0] = "timestamp = "+timestamp;
		attributes[1] = "stock_"+stockId;
		attributes[2] = "att_price";
		byte[] ciphertext;
		this.price.put("ws=1",new Ciphertext(cryptoHandler.enc_simple(this.stockId, attributes, price, this.timestamp)));
		for (int i=0; i<windowSizes.length; i++){
			ciphertext = cryptoHandler.enc_slidingWindow_Aggregate1(this.stockId, 0, windowSizes[i],
							attributes, price, this.timestamp);				
			this.price.put("ws=" + windowSizes[i], new Ciphertext(ciphertext));
		}	
		
		attributes[2] = "att_volume";
		this.volume.put("ws=1",new Ciphertext(cryptoHandler.enc_simple(this.stockId, attributes, volume, this.timestamp)));
		for (int i=0; i<windowSizes.length; i++){	
			ciphertext = cryptoHandler.enc_slidingWindow_Aggregate1(this.stockId, 1, windowSizes[i],
					attributes, volume, this.timestamp);	
			this.volume.put("ws=" + windowSizes[i], new Ciphertext(ciphertext));
		}
		long end = System.currentTimeMillis();
		
		log.info("encryption time = "+(end-start)+" with #windows = "+windowSizes.length);		
	}


	public int getTimestamp() {
		return timestamp;
	}


	public void setTimestamp(int timestamp) {
		this.timestamp = timestamp;
	}


	public int getStockId() {
		return stockId;
	}


	public void setStockId(int stockId) {
		this.stockId = stockId;
	}
	
	public Ciphertext getPrice(String val){
		return price.get(val);
	}

	public Map<String, Ciphertext> getPrice() {
		return price;
	}


	public void setPrice(Map<String, Ciphertext> price) {
		this.price = price;
	}

	public Ciphertext getVolume(String val){
		return this.volume.get(val);
	}

	public Map<String, Ciphertext> getVolume() {
		return volume;
	}


	public void setVolume(Map<String, Ciphertext> volume) {
		this.volume = volume;
	}


	public Log getLog() {
		return log;
	}		
	
}
